﻿using BarcodeDelay.logHelp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;
using SuperSocket.SocketBase.Protocol;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BarcodeDelay.FrameServer
{
    //public class WechatServer : AppServer<FrameAppSession, BinaryRequestInfo>
    public class WechatServer 
    {
        private string serverHost = "127.0.0.1";
        private int serverPort = 6666;
        private Dictionary<String, AppSession> sorterSessions = new Dictionary<String, AppSession>();
        private Hashtable htSiteSession = new Hashtable();

       
        private string strCameraKey = string.Empty;
        private AppSession lastAppSession;
        private Hashtable htAppSession = new Hashtable();

        public AppSession lastUsefullAppSession = null;
        public WechatServer()           
        {
            //this.serverKey = key;
        }

        public void BuildServer()
        {
            try
            {
                string port = ConfigurationManager.AppSettings["wechatServerPort"];
                if(port==null)
                {
                    port = "6666";
                }

                string ip = ConfigurationManager.AppSettings["wechatServer"];
                if (ip == null|| ip=="")
                {
                    ip = "127.0.0.1";
                }

                ServerConfig serverConfig = new ServerConfig()
                {
                    Ip = ip,
                    Port = Convert.ToInt32(port),
                    TextEncoding = "UTF-8",
                    MaxConnectionNumber = ServerConfig.DefaultMaxConnectionNumber,
                    Mode = SocketMode.Tcp,
                    MaxRequestLength = ServerConfig.DefaultMaxRequestLength*20,
                    KeepAliveTime = ServerConfig.DefaultKeepAliveTime,
                    KeepAliveInterval = ServerConfig.DefaultKeepAliveInterval,
                    ListenBacklog = ServerConfig.DefaultListenBacklog,
                    ReceiveBufferSize = ServerConfig.DefaultReceiveBufferSize*10,
                    SendTimeOut = ServerConfig.DefaultSendTimeout
                };

                var server = new AppServer();
                server.NewRequestReceived += Server_NewRequestReceived;
                server.NewSessionConnected += Server_NewSessionConnected;
                server.SessionClosed += Server_SessionClosed;
                bool success = server.Setup(serverConfig);
                if(success)
                {
                    LogHelper.Instance.writeLog("build server success ip " + ip.ToString()+" port:"+ port.ToString());
                }
                
                StoParams.Instance.isServerStart = server.Start();
                
            }
            catch(Exception ex)
            {

            }
           

           
 

            /*this.serverRunTask = new FrameRfidRunTask(this);
            if (ServiceManager.Instance.CurrentExecutor.Execute(this.serverRunTask) != 0)
            {
                SimbaCameraScale.Common.Log.Logger.LogError("FrameRfidServer", "【FrameServer】： Running task started failed");
                this.Stop();
            }*/
        }

        private void Server_SessionClosed(AppSession session, CloseReason value)
        {
            try
            {
                if (session == null)
                {
                    return;
                }

                String sessionId = session.SessionID;
                this.sorterSessions.Remove(sessionId);
                
                if(htAppSession.ContainsKey(session.SessionID))
                {
                    htAppSession.Remove(session.SessionID);
                }
                String clientHost = session.RemoteEndPoint.Address.ToString();
                int clientPort = session.RemoteEndPoint.Port;
                //SimbaCameraScale.Common.Log.Logger.LogInfo("FrameSessionClosed", "【FrameServer】： Client session : " + clientHost + ":" + clientPort + " closed");

                //this.TriggerClientClosedEvent(session);
            }
            catch (System.Exception ex)
            {
                //SimbaCameraScale.Common.Log.Logger.LogError("FrameRfidServer", "【FrameServer】： Close Session Failed : " + ex.Message);
            }
        }

        private void Server_NewSessionConnected(AppSession session)
        {
            try
            {
                string resMsg = "connect";
                byte[] initMsg = System.Text.Encoding.Default.GetBytes(resMsg);
                //session.Send(initMsg, 0, initMsg.Length);
                String sessionId = session.SessionID;

                //this.sorterSessions.Add(sessionId, session);
                strCameraKey = sessionId;

                if (!htAppSession.ContainsKey(sessionId))
                {
                    htAppSession[sessionId] = session;
                }


                String clientHost = session.RemoteEndPoint.Address.ToString();
                int clientPort = session.RemoteEndPoint.Port;
                lastAppSession = session;
                //this.TriggerClientConnectedEvent(session);
            }
            catch (System.Exception ex)
            {
                //SimbaCameraScale.Common.Log.Logger.LogError("FrameRfidServer", "【FrameServer】： Close Session Failed : " + ex.Message);
            }
        }

        private void Server_NewRequestReceived(AppSession session, StringRequestInfo requestInfo)
        {
            if (requestInfo == null)
            {
                return;
            }
            if (requestInfo.Body == null || requestInfo.Body.Length <= 0)
            {
                return;
            }

            FrameMessage command = new FrameMessage();
            command.Session = session;
            command.Content = requestInfo.Body;
            if(requestInfo.Body.Contains("register")&& requestInfo.Body.Contains("roomids"))
            {
                handleAppSessions(requestInfo.Body, session);
                //string msg = "helloworld";
                //byte[] resMsgContent = System.Text.Encoding.Default.GetBytes(msg);
                //sendContent(resMsgContent);
            }

            else if (requestInfo.Body.Contains("siteRegister") && requestInfo.Body.Contains("sites"))
            {
                handleSiteRegSessions(requestInfo.Body, session);
                //string msg = "helloworld";
                //byte[] resMsgContent = System.Text.Encoding.Default.GetBytes(msg);
                //sendContent(resMsgContent);
            }
            else
            {
                MsgMultiThreadHandler.Instance.HandleRawCommand(command);
            }
            
        }

        private void handleAppSessions(string registerMsg, AppSession session)
        {
            try
            {
                JObject jsonObjRes = (JObject)JsonConvert.DeserializeObject(registerMsg);
                JArray roomids = (JArray)jsonObjRes["roomids"];
                for (int i = 0; i < roomids.Count; i++)
                {
                    string room = roomids[i].ToString();
                    if(sorterSessions.ContainsKey(room))
                    {
                        sorterSessions.Remove(room);
                    }
                    sorterSessions.Add(room, session);

                    logHelp.LogHelper.Instance.writeLog("rec register msg:"+room);
                }
            }
            catch(Exception ex)
            {

            }
        }


        private void handleSiteRegSessions(string registerMsg, AppSession session)
        {
            try
            {
                JObject jsonObjRes = (JObject)JsonConvert.DeserializeObject(registerMsg);
                JArray sites = (JArray)jsonObjRes["sites"];
                for (int i = 0; i < sites.Count; i++)
                {
                    string site = sites[i].ToString();
                    htSiteSession[site] = session;                 

                    logHelp.LogHelper.Instance.writeLog("rec site register msg:" + site);
                }
            }
            catch (Exception ex)
            {

            }
        }




        private void FrameServerNewRequestReceived(FrameAppSession session, BinaryRequestInfo requestInfo)
        {
            int a = 0;
            /*if (requestInfo == null)
            {
                return;
            }
            if (requestInfo.Body == null || requestInfo.Body.Length <= 0)
            {
                return;
            }

            FrameMessage command = new FrameMessage();
            command.Session = session;
            command.Content = requestInfo.Body;

            MsgMultiThreadHandler.Instance.HandleRawCommand(command);*/
        }


        private void FrameServerNewSessionConnected(FrameAppSession session)
        {
            try
            {
                /*byte[] initMsg = { 0x05, 0x02, 0x01, 0xFF, 0x00, 0x01 };
                session.Send(initMsg, 0, initMsg.Length);
                String sessionId = session.SessionID;

                this.sorterSessions.Add(sessionId, session);
                strCameraKey = sessionId;


                String clientHost = session.RemoteEndPoint.Address.ToString();
                int clientPort = session.RemoteEndPoint.Port;*/

                //this.TriggerClientConnectedEvent(session);
            }
            catch (System.Exception ex)
            {
                //SimbaCameraScale.Common.Log.Logger.LogError("FrameRfidServer", "【FrameServer】： Close Session Failed : " + ex.Message);
            }
        }

        private void FrameSessionClosed(FrameAppSession session, CloseReason reason)
        {
            try
            {
                if (session == null)
                {
                    return;
                }

                String sessionId = session.SessionID;
                //this.sorterSessions.Remove(sessionId);
              

                String clientHost = session.RemoteEndPoint.Address.ToString();
                int clientPort = session.RemoteEndPoint.Port;
                //SimbaCameraScale.Common.Log.Logger.LogInfo("FrameSessionClosed", "【FrameServer】： Client session : " + clientHost + ":" + clientPort + " closed");

                //this.TriggerClientClosedEvent(session);
            }
            catch (System.Exception ex)
            {
                //SimbaCameraScale.Common.Log.Logger.LogError("FrameRfidServer", "【FrameServer】： Close Session Failed : " + ex.Message);
            }
        }


        public void sendContent(byte[] initMsg)
        {
            try
            {
                AppSession session = lastAppSession;
                if (session != null)
                {
                    session.Send(initMsg, 0, initMsg.Length);

                }
            }
            catch (Exception ex)
            {

            }
        }

        public void sendContentToAllChannel(byte[] initMsg)
        {
            try
            {
                foreach(DictionaryEntry de in htAppSession)
                {
                    AppSession session = (AppSession)de.Value;
                    if (session != null&& session.Connected)
                    {
                        session.Send(initMsg, 0, initMsg.Length);
                    }
                }
            }
            catch(Exception ex)
            {

            }

        }


        public void sendContent(byte[] initMsg,string roomid,string content)
        {
            try
            {
                if(this.sorterSessions.ContainsKey(roomid))
                {
                    AppSession session = this.sorterSessions[roomid];
                    if (session != null)
                    {
                        session.Send(initMsg, 0, initMsg.Length);
                        lastUsefullAppSession = session;
                    }
                }
                else
                {
                    content = content.Replace("：", ":");
                    content = content.Replace(":", " ");
                    content = content.Replace("  ", " ").Trim();
                    if (content.Contains("注册网点"))
                    {
                        string[] arr = content.Split(' ');
                        if(htSiteSession.ContainsKey(arr[1]))
                        {
                            AppSession session = htSiteSession[arr[1]] as AppSession;
                            sorterSessions.Add(roomid, session);

                            session.Send(initMsg, 0, initMsg.Length);

                        }
                       

                    }
                }
                
            }
            catch (Exception ex)
            {

            }
        }


        public void sendContentAck(byte[] initMsg, string roomid, string content)
        {
            try
            {
                if (lastUsefullAppSession != null)
                {
                    lastUsefullAppSession.Send(initMsg, 0, initMsg.Length);
                }
            }
            catch(Exception ex)
            {

            }
        }

    }
}
